// CollisionVisualDemo.java
package com.goldsprite.microhorigame.screens.examples.simplephysexamples;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Circle;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.goldsprite.gameframeworks.assets.GlobalAssets;
import com.goldsprite.gameframeworks.input.GameInputSystem;
import com.goldsprite.gameframeworks.screens.GScreen;
import com.goldsprite.gameframeworks.simplephys.shape.PhysCircle;
import com.goldsprite.gameframeworks.simplephys.shape.PhysRect;
import com.goldsprite.gameframeworks.utils.math.Vector2;
import com.goldsprite.gameframeworks.simplephys.collis.CollisionResult;
import com.goldsprite.gameframeworks.simplephys.collis.CollisionUtils;

import java.util.ArrayList;
import java.util.List;

public class CollisionVisualDemo extends GScreen {

	private OrthographicCamera camera;
	private ShapeRenderer shapeRenderer;
	private SpriteBatch batch;
	private BitmapFont font;

	// 测试实体
	private List<VisualEntity> entities;
	private VisualEntity playerEntity;

	// 控制变量
	private boolean showNormals = true;
	private boolean showOverlap = true;
	private boolean showDepth = true;
	private int currentTestScenario = 0;
	private boolean enableCollisionResponse = true;

	// 测试场景预设
	private final TestScenario[] testScenarios = new TestScenario[] {
		new TestScenario("AABB基础碰撞", this::setupAABBBase),
		new TestScenario("AABB角落碰撞", this::setupAABBCorner),
		new TestScenario("圆形碰撞", this::setupCircleCollision),
		new TestScenario("混合形状碰撞", this::setupMixedShapes),
		new TestScenario("穿透深度测试", this::setupDepthTest)
	};
	private Vector2 tmpVec2 = new Vector2();

	@Override
	public void create() {
		camera = getCamera();
		shapeRenderer = new ShapeRenderer();
		batch = new SpriteBatch();
		font = GlobalAssets.getInstance().smallFont;

		entities = new ArrayList<>();
		setupCurrentScenario();
	}

	@Override
	public void render0(float delta) {
		handleInput();


		// 固定时间步长更新
		fixedUpdateAccumulator += delta;
		while (fixedUpdateAccumulator >= FIXED_DELTA_TIME) {
			update(FIXED_DELTA_TIME);
			fixedUpdateAccumulator -= FIXED_DELTA_TIME;
		}
		draw();
	}

	private void handleInput() {
		// 场景切换
		for (int i = Input.Keys.NUM_1; i <= Input.Keys.NUM_5; i++) {
			if (Gdx.input.isKeyJustPressed(i)) {
				currentTestScenario = i - Input.Keys.NUM_1;
				setupCurrentScenario();
				break;
			}
		}

		// 显示选项切换
		if (Gdx.input.isKeyJustPressed(Input.Keys.N)) showNormals = !showNormals;
		if (Gdx.input.isKeyJustPressed(Input.Keys.O)) showOverlap = !showOverlap;
		if (Gdx.input.isKeyJustPressed(Input.Keys.F)) showDepth = !showDepth;
		if (Gdx.input.isKeyJustPressed(Input.Keys.T)) enableCollisionResponse = !enableCollisionResponse;

		// 玩家控制
		if (playerEntity != null) {
			playerEntity.velocity.set(0, 0);

			playerEntity.velocity.set(GameInputSystem.getInstance().getInputAction("Move").readValue());
			playerEntity.velocity.scl(speed);

			// 重置位置
			if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
				setupCurrentScenario();
			}
		}
	}

	private float fixedUpdateAccumulator = 0f;
	public static final float FIXED_DELTA_TIME = 1/15f; // 60Hz物理更新
	float speed = 300;
	private void update(float delta) {
		// 更新所有非静态实体
		for (VisualEntity entity : entities) {
			if (!entity.isStatic) {
				entity.update(delta);
			}
		}

		// 检测碰撞并更新状态
		for (int i = 0; i < entities.size(); i++) {
			VisualEntity entity = entities.get(i);
			entity.collisionResults.clear();
			if(entity.velocity.isZero()) continue;

			for (int j = 0; j < entities.size(); j++) {
				VisualEntity other = entities.get(j);
				if(entity == other) continue;

				CollisionResult result = new CollisionResult();
				CollisionResult result2 = new CollisionResult();

				boolean collided = false;
				if (entity.isCircle && other.isCircle) {
//					collided = CollisionUtils.calculateCollision(entity.circle, other.circle, result);
					collided = CollisionUtils.circleCircleDetector.ccdCollision(entity.lastPos, entity.circle, other.circle, result);
				} else if (entity.isCircle && !other.isCircle) {
//					collided = CollisionUtils.calculateCollision(entity.circle, other.rectangle, result);
					collided = CollisionUtils.circleRectDetector.ccdCollision(entity.lastPos, entity.circle, other.rectangle, result);
				} else if (!entity.isCircle && other.isCircle) {
					collided = CollisionUtils.calculateCollision(entity.rectangle, other.circle, result);
				} else if (!entity.isCircle && !other.isCircle) {
//					collided = CollisionUtils.calculateCollision(entity.rectangle, other.rectangle, result);
					collided = CollisionUtils.rectRectDetector.ccdCollision2(tmpVec2.set(entity.velocity).scl(delta), entity.rectangle, other.rectangle, result);
				}

				if (collided) {
					result2.collided = result.collided;
					result2.normal.set(result.normal).scl(-1);
					result2.depth = result.depth;

					entity.collisionResults.add(result2);
					other.collisionResults.add(result);
					Vector2 tmpVec = Vector2.obtain(result.normal).scl(result.depth);

					if(enableCollisionResponse){
						VisualEntity target = entity;
						if(target.isCircle){
							target.lastPos.set(target.circle.x, target.circle.y);
							target.circle.setPosition(target.circle.x + tmpVec.x, target.circle.y + tmpVec.y);
						}else{
							target.lastPos.set(target.rectangle.x, target.rectangle.y);
							target.rectangle.setPosition(target.rectangle.x + tmpVec.x, target.rectangle.y + tmpVec.y);
						}
					}
					tmpVec.close();
				}
			}
		}
	}

	private void draw() {
		// 绘制形状
		shapeRenderer.setProjectionMatrix(camera.combined);

		// 绘制实体填充
		shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
		for (VisualEntity entity : entities) {
			entity.renderFill(shapeRenderer);
		}
		shapeRenderer.end();

		// 绘制重叠区域
		if (showOverlap) {
			drawOverlapAreas();
		}

		// 绘制边框
		shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
		for (VisualEntity entity : entities) {
			entity.renderBorder(shapeRenderer);
		}
		shapeRenderer.end();

		// 绘制法线和深度
		if (showNormals || showDepth) {
			drawCollisionVisualizations();
		}

		// 绘制UI信息
		drawUI();
	}

	private void drawOverlapAreas() {
		shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
		shapeRenderer.setColor(1, 1, 0, 0.3f); // 半透明黄色

		for (VisualEntity entity : entities) {
			for (CollisionResult result : entity.collisionResults) {
				// 这里可以绘制更精确的重叠区域，简化版本使用实体区域
				if (entity.isCircle) {
					shapeRenderer.circle(entity.circle.x, entity.circle.y, entity.circle.radius * 0.7f);
				} else {
					shapeRenderer.rect(entity.rectangle.x + entity.rectangle.width * 0.15f,
						entity.rectangle.y + entity.rectangle.height * 0.15f,
						entity.rectangle.width * 0.7f,
						entity.rectangle.height * 0.7f);
				}
			}
		}
		shapeRenderer.end();
	}

	private void drawCollisionVisualizations() {
		shapeRenderer.begin(ShapeRenderer.ShapeType.Line);

		for (VisualEntity entity : entities) {
			for (CollisionResult result : entity.collisionResults) {
				Vector2 center = entity.getCenter();

				// 绘制法线
				if (showNormals) {
					shapeRenderer.setColor(Color.BROWN);
					Vector2 normalEnd = new Vector2(center).add(
						result.normal.x * 40, result.normal.y * 40);
					shapeRenderer.line(center.x, center.y, normalEnd.x, normalEnd.y);
					drawArrow(center.x, center.y, normalEnd.x, normalEnd.y, Color.BROWN);
				}

				// 绘制穿透深度
				if (showDepth && result.depth > 0) {
					shapeRenderer.setColor(Color.RED);
					Vector2 depthEnd = new Vector2(center).add(
						result.normal.x * result.depth, result.normal.y * result.depth);
					shapeRenderer.line(center.x, center.y, depthEnd.x, depthEnd.y);

					// 深度指示点
					shapeRenderer.setColor(Color.RED);
					shapeRenderer.circle(depthEnd.x, depthEnd.y, 3);
				}
			}
		}

		shapeRenderer.end();
	}

	private void drawArrow(float x1, float y1, float x2, float y2, Color color) {
		float arrowLength = 8;
		float arrowAngle = (float) Math.toRadians(25);
		float angle = (float) Math.atan2(y2 - y1, x2 - x1);

		float x3 = x2 - arrowLength * (float) Math.cos(angle - arrowAngle);
		float y3 = y2 - arrowLength * (float) Math.sin(angle - arrowAngle);
		float x4 = x2 - arrowLength * (float) Math.cos(angle + arrowAngle);
		float y4 = y2 - arrowLength * (float) Math.sin(angle + arrowAngle);

		shapeRenderer.setColor(color);
		shapeRenderer.line(x2, y2, x3, y3);
		shapeRenderer.line(x2, y2, x4, y4);
	}

	private void drawUI() {
		batch.begin();

		// 场景信息
		TestScenario scenario = testScenarios[currentTestScenario];
		font.draw(batch, "场景: " + scenario.name, 10, getViewSize().y - 20);
		font.draw(batch, "控制: 1-5切换场景, WASD移动, 空格重置", 10, getViewSize().y - 40);
		font.draw(batch, "显示: N-法线(" + showNormals + "), O-重叠(" + showOverlap + "), F-深度(" + showDepth + "), T-阻挡("+enableCollisionResponse+")", 10, getViewSize().y - 60);

		// 碰撞信息
		int collisionCount = 0;
		for (VisualEntity entity : entities) {
			if (!entity.collisionResults.isEmpty()) {
				collisionCount++;
			}
		}
		font.draw(batch, "碰撞数量: " + collisionCount, 10, getViewSize().y - 80);

		// 实体信息
		float yPos = getViewSize().y - 120;
		for (int i = 0; i < entities.size() && i < 5; i++) {
			VisualEntity entity = entities.get(i);
			String info = String.format("实体%d: %s %s", i + 1,
				entity.isCircle ? "圆形" : "矩形",
				entity.isStatic ? "(静态)" : "(动态)");
			font.draw(batch, info, 10, yPos);
			yPos -= 20;
		}

		batch.end();
	}

	private void setupCurrentScenario() {
		entities.clear();
		testScenarios[currentTestScenario].setup.run();
	}

	// 测试场景设置
	private void setupAABBBase() {
		// 玩家控制的矩形
		playerEntity = new VisualEntity(100, 100, 50, 50, Color.BLUE, false);

		// 静态测试矩形
		entities.add(new VisualEntity(400, 300, 80, 60, Color.RED, true));
		entities.add(new VisualEntity(200, 400, 40, 40, Color.GREEN, true));
		entities.add(playerEntity);
	}

	private void setupAABBCorner() {
		playerEntity = new VisualEntity(150, 150, 40, 40, Color.BLUE, false);

		entities.add(new VisualEntity(300, 300, 60, 60, Color.RED, true));
		entities.add(new VisualEntity(250, 250, 50, 50, Color.GREEN, true));
		entities.add(playerEntity);
	}

	private void setupCircleCollision() {
		playerEntity = new VisualEntity(100, 100, 25, Color.BLUE, false);

		entities.add(new VisualEntity(400, 300, 30, Color.RED, true));
		entities.add(new VisualEntity(200, 400, 20, Color.GREEN, true));
		entities.add(new VisualEntity(540, 200, 70, Color.ORANGE, true));
		entities.add(new VisualEntity(350, 150, 40, 40, Color.ORANGE, true));
		entities.add(playerEntity);
	}

	private void setupMixedShapes() {
		playerEntity = new VisualEntity(100, 100, 40, 40, Color.BLUE, false);

		entities.add(new VisualEntity(400, 300, 30, Color.RED, true)); // 圆形
		entities.add(new VisualEntity(300, 200, 60, 40, Color.GREEN, true)); // 矩形
		entities.add(new VisualEntity(500, 400, 25, Color.ORANGE, true)); // 圆形
		entities.add(playerEntity);
	}

	private void setupDepthTest() {
		playerEntity = new VisualEntity(100, 100, 60, 60, Color.BLUE, false);

		entities.add(new VisualEntity(380, 300, 80, 80, Color.RED, true)); // 轻微重叠
		entities.add(new VisualEntity(200, 350, 100, 40, Color.GREEN, true)); // 中等重叠
		entities.add(new VisualEntity(300, 100, 50, 100, Color.ORANGE, true)); // 深度重叠
		entities.add(playerEntity);
	}

	@Override
	public void dispose() {
		shapeRenderer.dispose();
		batch.dispose();
		font.dispose();
	}

	// 测试场景数据结构
	private static class TestScenario {
		String name;
		Runnable setup;

		TestScenario(String name, Runnable setup) {
			this.name = name;
			this.setup = setup;
		}
	}

	// 增强的可视化实体类
	private static class VisualEntity {
		public final PhysRect rectangle;
		public final PhysCircle circle;
		public final boolean isCircle;
		public final boolean isStatic;
		public final Color color;
		public final Vector2 lastPos;
		public final Vector2 velocity;
		public final List<CollisionResult> collisionResults;

		// 矩形构造函数
		public VisualEntity(float x, float y, float width, float height, Color color, boolean isStatic) {
			this.rectangle = new PhysRect(x, y, width, height);
			this.circle = null;
			this.isCircle = false;
			this.isStatic = isStatic;
			this.color = color;
			this.lastPos = new Vector2();
			this.velocity = new Vector2();
			this.collisionResults = new ArrayList<>();
		}

		// 圆形构造函数
		public VisualEntity(float x, float y, float radius, Color color, boolean isStatic) {
			this.rectangle = null;
			this.circle = new PhysCircle(x, y, radius);
			this.isCircle = true;
			this.isStatic = isStatic;
			this.color = color;
			this.lastPos = new Vector2();
			this.velocity = new Vector2();
			this.collisionResults = new ArrayList<>();
		}

		public Vector2 getCenter() {
			if (isCircle) {
				return new Vector2(circle.x, circle.y);
			} else {
				return new Vector2(rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2);
			}
		}

		public void update(float delta) {
			if (!isStatic && !velocity.isZero()) {
				if (isCircle) {
					lastPos.set(circle.x, circle.y);
					circle.x += velocity.x * delta;
					circle.y += velocity.y * delta;
				} else {
					lastPos.set(rectangle.x, rectangle.y);
					rectangle.x += velocity.x * delta;
					rectangle.y += velocity.y * delta;
				}
			}
		}

		public void renderFill(ShapeRenderer shapeRenderer) {
			Color renderColor = collisionResults.isEmpty() ? color : Color.CYAN;
			shapeRenderer.setColor(renderColor);

			if (isCircle) {
				shapeRenderer.circle(circle.x, circle.y, circle.radius);
			} else {
				shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
			}
		}

		public void renderBorder(ShapeRenderer shapeRenderer) {
			shapeRenderer.setColor(isStatic ? Color.BLACK : Color.WHITE);

			if (isCircle) {
				shapeRenderer.circle(circle.x, circle.y, circle.radius);
			} else {
				shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
			}
		}
	}
}
